package com.dcrzl.gazgmh.module.sys.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dcrzl.gazgmh.common.entity.sys.SysConfig;
import com.dcrzl.gazgmh.common.entity.sys.SysLog;
import com.dcrzl.gazgmh.common.entity.sys.SysRole;
import com.dcrzl.gazgmh.common.entity.sys.SysUser;
import com.dcrzl.gazgmh.common.enums.UserTypeEnum;
import com.dcrzl.gazgmh.common.mapper.sys.SysUserMapper;
import com.dcrzl.gazgmh.common.service.impl.BaseServiceImpl;
import com.dcrzl.gazgmh.common.utils.*;
import com.dcrzl.gazgmh.module.sys.service.SysRoleService;
import com.dcrzl.gazgmh.module.sys.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service("sysUserService")
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysConfigServiceImpl sysConfigService;

    /**
     *
     * @param sysUser
     * @return
     */
    @Override
    public Result<Integer> update(SysUser sysUser) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Objects.nonNull(sysUser.getId()), SysUser::getId, sysUser.getId());
        wrapper.eq(Objects.nonNull(sysUser.getPhone()), SysUser::getPhone, sysUser.getPhone());
        wrapper.eq(Objects.nonNull(sysUser.getMail()), SysUser::getMail, sysUser.getMail());
        wrapper.eq(Objects.nonNull(sysUser.getPassword()), SysUser::getPassword, sysUser.getPassword());
        return super.update(sysUser, wrapper);
    }

    @Override
    public Result<SysUser> selectOne(SysUser sysUser) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Objects.nonNull(sysUser.getId()),SysUser::getId,sysUser.getId());
        wrapper.eq(Objects.nonNull(sysUser.getUserCode()),SysUser::getUserCode,sysUser.getUserCode());
        wrapper.eq(Objects.nonNull(sysUser.getMail()),SysUser::getMail,sysUser.getMail());
        wrapper.eq(Objects.nonNull(sysUser.getUsername()),SysUser::getUsername,sysUser.getUsername());
        wrapper.eq(Objects.nonNull(sysUser.getPhone()),SysUser::getPhone,sysUser.getPhone());
        wrapper.eq(Objects.nonNull(sysUser.getPassword()),SysUser::getPassword,sysUser.getPassword());
        return super.selectOne(wrapper);
    }

    @Override
    public Result<List<SysUser>> selectList(SysUser sysUser) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        return super.selectList(wrapper);
    }

    @Override
    public PageInfo<SysUser> selectPage(SysUser sysUser) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Objects.nonNull(sysUser.getUserCode()),SysUser::getUserCode,
                "%"+sysUser.getUserCode()+"%");
        wrapper.like(Objects.nonNull(sysUser.getMail()),SysUser::getMail,
                "%"+sysUser.getMail()+"%");
        wrapper.like(Objects.nonNull(sysUser.getPhone()),SysUser::getPhone,
                "%"+sysUser.getPhone()+"%");
        wrapper.like(Objects.nonNull(sysUser.getTrueName()),SysUser::getTrueName,
                "%"+sysUser.getTrueName()+"%");
        wrapper.like(Objects.nonNull(sysUser.getUsername()),SysUser::getUsername,
                "%"+sysUser.getUsername()+"%");
        wrapper.ge(Objects.nonNull(sysUser.getRoleId()),SysUser::getRoleId,sysUser.getRoleId());
        return super.selectPage(sysUser, wrapper);
    }

    /**
     * 登录
     * @param sysUser
     * @return
     */
    @Override
    public Result<Object> login(SysUser sysUser) {
        Result<SysUser> sysUserResult = this.selectOne(sysUser);
        Result<Object> result = new Result<>();
        if(sysUserResult.isSuccess()){
            sysUser = sysUserResult.getData();
            if(sysUser.getStatus()== SysConstant.DATA_DELETE_STATUS){
                return result.setSuccess(false).setMsg("该账户已冻结").setCode(SysConstant.FREEZE_CODE_RES);
            }else{
                Date passwordExpireDate = sysUser.getPasswordExpireDate();
                Date nowDate = new Date();
                if(passwordExpireDate.before(nowDate)){
                    return result.setSuccess(false).setMsg("该账户密码已过期，请修改密码").setCode(SysConstant.FREEZE_CODE_RES);
                }
                Long userId = sysUser.getId();
                Long roleId = sysUser.getRoleId();
                Map<String,Object> map = new HashMap<>();
                map.put("roleId",roleId);
                map.put("userId", userId);
                map.put("username", sysUser.getUsername());
                map.put("userType", UserTypeEnum.SYS_USER_TYPE.getCode());
                String jti = SysUtils.getUUID();
                String jwt = JwtUtils.createJwt(jti, map, SysConstant.TOKEN_EXPIRED_TIME);
                String userToken = EncryptionUtil.getEncryptDESData(JSON.toJSONString(map), jwt);
                Map<String,Object> resMap = new HashMap<>();
                resMap.put("userToken",userToken);
                resMap.put("token",jwt);
                result.setData(resMap);

                //设置会话时间
                Result<SysConfig> sysConfigResult = sysConfigService.selectOne(new SysConfig().setStatus(SysConstant.DATA_NORMAL_STATUS));
                int time = 30;
                if(sysConfigResult.isSuccess()){
                    SysConfig sysConfig = sysConfigResult.getData();
                    time = sysConfig.getSessionTime();
                }
                stringRedisTemplate.opsForValue().set(userId+":"+UserTypeEnum.SYS_USER_TYPE.getCode(),
                        userId+"",time, TimeUnit.MINUTES);
                //更新登陆时间
                this.updateById(new SysUser().setId(userId).setLoginTime(new Date()));

                return result;
            }
        }
        return result.setMsg("账号或密码错误").setCode(SysConstant.PASSWORD_ERROR_CODE_RES);
    }

    @Override
    public PageInfo<SysUser> selectURolePage(SysUser sysUser) {
        PageInfo<SysUser> sysUserPageInfo = this.selectPage(sysUser);
        List<SysUser> userList = sysUserPageInfo.getList();
        Set<Serializable> roleIdSet = new HashSet<>();
         userList.forEach(user->{
             roleIdSet.add(user.getRoleId());
         });
        Result<List<SysRole>> listResult = sysRoleService.selectBatchIds(roleIdSet);
        if(listResult.isSuccess()){
            List<SysRole> sysRoleList = listResult.getData();
            Map<Long,String> map = new HashMap<>();
            sysRoleList.forEach(sysRole -> {
                map.put(sysRole.getId(),sysRole.getRoleName());
            });
            userList.forEach(user->{
                user.setRoleName(map.get(user.getRoleId()));
            });
        }
        return sysUserPageInfo;
    }

    @Override
    public Result<Integer> updatePasswordById(SysUser sysUser) {
        Result<SysConfig> sysConfigResult = sysConfigService.selectOne(new SysConfig().setStatus(SysConstant.DATA_NORMAL_STATUS));
        if (sysConfigResult.isSuccess()) {
            SysConfig sysConfig = sysConfigResult.getData();
            Integer passwordValidDay = sysConfig.getPasswordValidDay();
            Date date = SysUtils.dateAddDay(new Date(), passwordValidDay);
            sysUser.setPasswordExpireDate(date);
        }
        return this.updateById(sysUser);
    }


    @Override
    public Result<Integer> removeById(Serializable id) {
        SysUser sysUser = new SysUser().setStatus(SysConstant.DATA_DELETE_STATUS)
                .setId((Long) id);
        return ResultUtils.removeResult(baseMapper.updateById(sysUser));
    }
}